﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace chess
{

    class csMoves
    {
        List<csStepSequence> _moves = null;

        public csMoves(string strMove)
        {
            this._moves = new List<csStepSequence>();
            string[] moves = strMove.Split('|');
            foreach (string strStepSequence in moves)
            {
                string[] stepSequencePart = strStepSequence.Split(':');
                string evaluator = stepSequencePart[0];
                csStepSequence stepSequence = new csStepSequence(Convert.ToInt32(evaluator));

                string[] steps = stepSequencePart[1].Split('+');
                foreach(string strStep in steps)
                {
                    csStep tmpStep = new csStep(strStep);
                    stepSequence.Add(tmpStep);
                }

                this._moves.Add(stepSequence);
            }
        }


        public List<csField> Evaluate(csFig fig, csBoard board, enumFieldMarkerType marker)
        {
            Dictionary<string, csField> dictMoves = new Dictionary<string, csField>();
            List<csField> result = new List<csField>();

            // Legt die Bewegungsrichtung fest. Züge, die von Schwarz von oben her ausgeführt werden
            // werden spiegelverkehrt durchgeführt
            int multiplier = 1;
            if (fig.Party == enumFigParty.Black)
            {
                multiplier = -1;
            }
            
            //foreach (csStepSequence zug in this._moves)
            for (int i = 0; i < this._moves.Count; i++)
            {
                csStepSequence zug = this._moves[i];

                int evaluator = zug.Evaluator;

                int aktPosSpalte = fig.Spalte;
                int aktPosZeile = fig.Zeile;

                int zielSpalte = aktPosSpalte;
                int zielZeile = aktPosZeile;

                bool auswertungAbbrechen = false;

                for (int j = 0; j < evaluator; j++)
                {

                    // Wenn die Figur kein Bauer ist, ist der erste Zug sowieso irrelevant
                    /*
                    if (fig.FigType != enumFigType.B)
                    {
                        fig.ErsterZugGemacht = true;
                    }
                    */

                    // Erster Zug einer Figur wird gesondert behandelt, um den Eröffnungszug des Bauern
                    // über zwei Felder zu bearbeiten
                    // Es gibt zwei Bedingungen, wann diese Schleife durchlaufen werden muss:
                    // 1. Wenn eine Figur den ersten Zug noch nicht gemacht hat und jetzt die Bearbeitung 
                    //    der Schritte des ersten Zuges ansteht
                    // 2. Wenn der erste Zug gemacht wurde und die Schritte der weiteren Züge bearbeitet
                    //    werden sollen
                    if (((fig.ErsterZugGemacht == false) && (i == 0)) || ((fig.ErsterZugGemacht == true) && (i > 0)))
                    {
                        foreach (csStep schritt in zug.GetSteps)
                        {
                            int schrittLaengeinFeldern = schritt.Number;
                            char richtung = schritt.Direction;

                            switch (richtung)
                            {
                                case 'F':
                                    zielZeile -= schrittLaengeinFeldern * multiplier;
                                    break;
                                case 'B':
                                    zielZeile += schrittLaengeinFeldern * multiplier;
                                    break;
                                case 'L':
                                    zielSpalte -= schrittLaengeinFeldern * multiplier;
                                    break;
                                case 'R':
                                    zielSpalte += schrittLaengeinFeldern * multiplier;
                                    break;
                                default:
                                    break;
                            }

                        }
                        //fig.ErsterZugGemacht = true;
                    }

                    bool zugSpeichern = false;
                    // Am Zugende wird der Status des Zielfeldes kontrolliert
                    // 1. Das Feld ist frei und der Zug kann durchgeführt werden
                    // 2. Das Feld ist durch eine andere Spielfigur besetzt
                    // 3. Das Feld ist durch eine eigene Spielfigur besetzt

                    // Aber nur, wenn es auf dem Schachbrett liegt
                     if ((zielSpalte > -1) && (zielSpalte < 8) && (zielZeile > -1) && (zielZeile < 8))
                    {

                        csField zielFeld = board.GetField(zielSpalte, zielZeile);

                        // Ausnahmefall Bauer: Gerade ziehen, jeweils ein Feld; Schlagen nur diagonal
                        // Hier die Behandlung der Züge für alle anderen...
                        if (fig.FigType != enumFigType.B)
                        {
                            // Fall 1 & 2
                            // 1. Das Feld ist frei und der Zug kann durchgeführt werden
                            if (zielFeld.Status == enumFieldStatus.Empty)
                            {
                                zugSpeichern = true;
                            }

                            // 2. Das Feld ist durch eine andere Spielfigur besetzt
                            if (((zielFeld.Status == enumFieldStatus.White) && (fig.Party == enumFigParty.Black))
                            || ((zielFeld.Status == enumFieldStatus.Black) && (fig.Party == enumFigParty.White)))
                            {
                                zugSpeichern = true;
                                auswertungAbbrechen = true;
                            }

                            // Fall 3
                            // 3. Das Feld ist durch eine eigene Spielfigur besetzt
                            if (((zielFeld.Status == enumFieldStatus.White) && (fig.Party == enumFigParty.White))
                            || ((zielFeld.Status == enumFieldStatus.Black) && (fig.Party == enumFigParty.Black)))
                            {
                                zugSpeichern = false;
                                auswertungAbbrechen = true;
                            }
                        } else
                        {
                            // Hier die Behandlung der Bauer-Züge
                            // ist die Figur ein Bauer, dann
                            // Fall 1: Das Feld ist frei und der Zug kann durchgeführt werden 
                            // muss aber in der gleichen Spalte wie das Ausgangsfeld liegen
                            // Nachtrag 06.12.15: Zur Ermittlung eines relevanten Zielfeldes muss dieses frei sein, wenn es sich in der
                            // gleichen Spalte befindet
                            if (marker == enumFieldMarkerType.destination)
                            {
                                if ((zielFeld.Status == enumFieldStatus.Empty) && (zielSpalte == fig.Spalte))
                                {
                                    zugSpeichern = true;
                                }
                            }
                            // Das Feld vor der Figur ist für die Ermittlung einer Bedrohung durch einen Bauern unerheblich, da der
                            // Bauer nur nach schräg-links oder schräg-rechts schlagen darf
                            if (marker == enumFieldMarkerType.offended)
                            {
                                // Nothing TODO
                            }

                            // Fall 2: Das Feld ist durch eine andere Spielfigur besetzt, die Zielspalte
                            // muss jetzt aber eine andere sein, was durch das in TOOLS definierte
                            // Zugschema erreicht wird
                            // Nachsatz 17.11.15: Die Zeile muss dann aber auch differieren
                            // Nachsatz 06.12.15: Zur Ermittlung eines relevanten Schlagfeldes muss sich eine Figur mit anderer Farbe
                            // auf dem evaluierten Feld befinden
                            if (marker == enumFieldMarkerType.destination)
                            {
                                if ((((zielFeld.Status == enumFieldStatus.White) && (fig.Party == enumFigParty.Black))
                                || ((zielFeld.Status == enumFieldStatus.Black) && (fig.Party == enumFigParty.White)))
                                && (zielSpalte != fig.Spalte) && (zielZeile != fig.Zeile))
                                {
                                    zugSpeichern = true;
                                }
                            }
                            // ZurErmittlung eines bedrohten Feldes muss sich nicht unbedingt eine Figur auf dem evaluierten Feld
                            // befinden
                            if (marker == enumFieldMarkerType.offended)
                            {
                                if ((zielSpalte != fig.Spalte) && (zielZeile != fig.Zeile))
                                {
                                    zugSpeichern = true;
                                }
                            }

                            // Fall 3: mit Bauernzusatz!
                            // 3. Das Feld liegt in der gleichen Spalte und ist durch eine eigene oder andere Spielfigur besetzt
                            // Durch das Zugschema wird eine weitere Überprüfung als bis auf das erste Freld vor der Figur
                            // unterbunden
                            if ((zielFeld.Status != enumFieldStatus.Empty)&&(zielFeld.Spalte == fig.Spalte))
                            {
                                zugSpeichern = false;
                                auswertungAbbrechen = true;
                            }

                            // Fall 4: Links oder rechts vom aktuellen Bauern steht ein gegnerischer
                            // Bauer, dessen letzer Zug ein Eröffnungszug über 2 Felder war.
                            // ("En-Passant-Regel")
                            /* Debug-Einstellung, um EnPassant-Regel zu testen
                            if ((zielSpalte == 4)&&(zielZeile ==3))
                            {
                                zielFeld.GetFig.EnPassantGeradeAusgefuehrt = true;
                            }
                            */
                            // Nachsatz 06.12.15: Zur Ermittlung eines relevanten Schlagfeldes muss sich eine Figur mit anderer Farbe
                            // auf dem evaluierten Feld befinden
                            if (marker == enumFieldMarkerType.destination)
                            {
                                if ((((zielFeld.Status == enumFieldStatus.White) && (fig.Party == enumFigParty.Black))
                                || ((zielFeld.Status == enumFieldStatus.Black) && (fig.Party == enumFigParty.White)))
                                && (zielSpalte != fig.Spalte) && (zielZeile == fig.Zeile)
                                && (zielFeld.GetFig.FigType == enumFigType.B)
                                && zielFeld.GetFig.EnPassantGeradeAusgefuehrt == true)
                                {
                                    zugSpeichern = true;
                                }
                            }
                            // Zusätzliche Fallprüfung zum Nachtrag vom 06.12.15
                            if ((marker == enumFieldMarkerType.offended)&&(zielFeld.GetFig != null))
                            {
                                if ((zielSpalte != fig.Spalte) && (zielZeile == fig.Zeile)
                                && (zielFeld.GetFig.FigType == enumFigType.B))
                                {
                                    zugSpeichern = true;
                                }
                            }
                        }

                        // Soll der zug gespeichert werden...
                        if (zugSpeichern == true)
                        {
                            // dann speichern!
                            csField field = board.GetField(zielSpalte, zielZeile);
                            string strKey = string.Format("{0}:{1}", zielSpalte, zielZeile);
                            // ...aber nur, wenn sich nicht schon der gleiche Zug in der Ergebnisliste befindet
                            if (!dictMoves.ContainsKey(strKey))
                            {
                                dictMoves.Add(strKey, field);
                                result.Add(field);
                            }
                        }
                    }

                    if (auswertungAbbrechen == true)
                    {
                        j = evaluator + 1;
                    }
                }

                // Nachdem der erste Zug gemacht wurde und das ErsterZugGemacht-Flag auf TRUE steht
                // (daher abgefragt, bevor es hier gesetzt wird) greift die EnPassantRegel nicht mehr
                // und das FLag wird wieder zurückgesetzt
                // WURDE AUSKOMMENTIERT: DAS DARF NUR BEI DER DURCHFÜHRUNG EINES ZUGS GEMACHT WERDEN
                // NIEMALS BEI DER EVALUIERUNG
                /*
                if (fig.ErsterZugGemacht == true)
                {
                    fig.EnPassantGeradeAusgefuehrt = false;
                }
                */

                // Es wurde gerade ein Zug gemacht, ob's der Erste war ist nicht wichtig!
                //fig.ErsterZugGemacht = true;

                // EnPassant_flag setzen, wenn Figur ein Bauer ist und gerade einen 2 Schritte-Zug 
                // gemacht hat
                /*
                if ((fig.FigType == enumFigType.B)&&(evaluator == 2))
                {
                    fig.EnPassantGeradeAusgefuehrt = true;
                }
                */

            }

            return result;
        }

    }
}
